﻿using AngleSharp.Dom;
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text.Json;
using static AntDesign.IconType;

namespace OnlineOpinionAnalysis.Server.HostService
{
	public class SpiderHelper
	{
		public const string UserAgent =
		"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36";
		public static HttpClientHandler Handler { get; }
		public static HttpClient HttpClient { get; }
		public static HtmlParser HtmlParser { get; }



		static SpiderHelper()
		{
			Handler = new HttpClientHandler();
			HttpClient = new HttpClient(Handler);
			HttpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.57");
			//HttpClient.DefaultRequestHeaders.Add("X-Requested-With","XMLHttpRequest");
			//HttpClient.DefaultRequestHeaders.Add("Host","index.baidu.com");
			//HttpClient.DefaultRequestHeaders.Add("Connection","keep-alive");
			//HttpClient.DefaultRequestHeaders.Add("Cookie", "BDUSS=kxuSTcyb1d1Z3NQb2JlemQ5dU5BaTZCNkJQUHR2a09ZSURDam95ZVZJbGhZa3BrRVFBQUFBJCQAAAAAAAAAAAEAAADIErhPTUNfWkhBTkdaSEFORwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGHVImRh1SJkf");


			HtmlParser = new();
		}

		public static async Task<IHtmlDocument> GetHtmlDocumentAsync(string url)
		{
			try
			{
				var responseHtml = await HttpClient.GetStringAsync(url);
				var document = await HtmlParser.ParseDocumentAsync(responseHtml);
				
				return document;
			}
			catch (HttpRequestException e)
			{
				Console.WriteLine($"Http请求异常:{e.Message}");
				return null;
			}
			catch (NullReferenceException e)
			{
				Console.WriteLine($"返回值为空:{e.Message}");
				return null;
			}
		}


		public static async Task<string> GetBaiduInfo()
		{
       
            string keyword = "mc";
			var document=await GetHtmlDocumentAsync($"https://index.baidu.com/v2/main/index.html#/trend/{keyword}?words={keyword}");
			foreach (var item in document.QuerySelectorAll("p")) 
			{
				Console.WriteLine(item.TextContent);
			}
			return "2";
		}


		//不是怎么还是用不到分析库啊。。
		public static async Task GetWeiboSuper()
		{
            //https://m.weibo.cn/api/container/getIndex?jumpfrom=weibocom&containerid=100808e1f868bf9980f09ab6908787d7eaf0f0_-_feed
            string index = $"https://m.weibo.cn/p/100808e1f868bf9980f09ab6908787d7eaf0f0/super_index?jumpfrom=weibocom";
            string result = await HttpClient.GetStringAsync(index);
            var document = await HtmlParser.ParseDocumentAsync(result);
			var data = document.All.Where(m => m.LocalName == "strong" && m.ClassName == "W_f12");

			foreach (var item in data)
			{
				Console.WriteLine(item.TextContent);
            }
           

        }

		
		public static async Task<string> GetZhiHu()
		{  
            string index = $" https://www.zhihu.com/topic/21874407/hot";
            string result = await HttpClient.GetStringAsync(index);
            var document = await HtmlParser.ParseDocumentAsync(result);
            // 获取特定标签的内容
			var data = document.All.
                Where(m => m.LocalName == "strong" && m.ClassName == "NumberBoard-itemValue");

            return data.FirstOrDefault().GetAttribute("title");
		}

        //https://www.bilibili.com/read/cv12357091
        //https://github.com/SocialSisterYi/bilibili-API-collect
        public static async Task GetBiliBiliApi()
		{
			string index= $"https://api.bilibili.com/x/web-interface/ranking/v2?rid=4";
			string result=  await HttpClient.GetStringAsync(index);

            using (JsonDocument document = JsonDocument.Parse(result))
            {
                JsonElement root = document.RootElement;
                JsonElement dataElement = root.GetProperty("data");
                foreach (JsonElement video in dataElement.GetProperty("list").EnumerateArray())
                {
					if(video.TryGetProperty("tname",out JsonElement tname)&& video.TryGetProperty("title", out JsonElement title))
					{
						Console.WriteLine($"{tname}:{title}");
					}
                 
                }
            }
        }
        //        名称 代号  rid 简介  url路由
        //知识(主分区) knowledge	36		/v/knowledge
        //科学科普    science	201	回答你的十万个为什么	/v/knowledge/science
        //社科·法律·心理(原社科人文、原趣味科普人文) social_science	124	基于社会科学、法学、心理学展开或个人观点输出的知识视频	/v/knowledge/social_science
        //人文历史    humanity_history	228	看看古今人物，聊聊历史过往，品品文学典籍	/v/knowledge/humanity_history
        //财经商业    business	207	说金融市场，谈宏观经济，一起畅聊商业故事	/v/knowledge/finance
        //校园学习    campus	208	老师很有趣，学生也有才，我们一起搞学习	/v/knowledge/campus
        //职业职场    career	209	职业分享、升级指南，一起成为最有料的职场人	/v/knowledge/career
        //设计·创意 design	229	天马行空，创意设计，都在这里	/v/knowledge/design
        //野生技术协会  skill	122	技能党集合，是时候展示真正的技术了	/v/knowledge/skill
        /// <summary>
        /// 获取Bilibili特定分区的视频榜单(100)
        /// </summary>
        /// <returns></returns>
        public static async Task<List<BiliVideo>> GetBiliBiliVideoOrder(ILogger logger, int rid = 1)
        {
            List<BiliVideo> biliVideos = new(100);
            // 发出请求
            string index = $"https://api.bilibili.com/x/web-interface/ranking/v2?rid={rid}";
            string result = await HttpClient.GetStringAsync(index);
            // 创建Json文档树
            using JsonDocument document = JsonDocument.Parse(result);
            JsonElement root = document.RootElement;
            // 尝试获取数据
            if (!root.TryGetProperty("data", out JsonElement dataElement))
            {
                logger.LogError($"[{DateTime.Now}]爬取[{index}]的数据失败，错误码:{root.GetProperty("code").GetString()}");
                return new List<BiliVideo>();
            }
            try
            {
                foreach (JsonElement video in dataElement.GetProperty("list").EnumerateArray())
                {
                    try
                    {
                        JsonElement statElement = video.GetProperty("stat");

                        BiliVideo biliVideo = new()
                        {
                            AvId = video.GetProperty("aid").GetInt32(),
                            BvId = video.GetProperty("bvid").GetString(),
                            Tid = video.GetProperty("tid").GetInt32(),
                            TName = video.GetProperty("tname").GetString(),
                            Title = video.GetProperty("title").GetString(),
                            Description = video.GetProperty("desc").GetString(),
                            AuthorId = video.GetProperty("owner").GetProperty("mid").GetInt32(),
                            Duration = video.GetProperty("duration").GetInt32(),
                            View = statElement.GetProperty("view").GetInt32(),
                            Danmaku = statElement.GetProperty("danmaku").GetInt32(),
                            Reply = statElement.GetProperty("reply").GetInt32(),
                            Favorite = statElement.GetProperty("favorite").GetInt32(),
                            Coin = statElement.GetProperty("coin").GetInt32(),
                            Share = statElement.GetProperty("share").GetInt32(),
                            Like = statElement.GetProperty("like").GetInt32(),
                            VV = statElement.GetProperty("vv").GetInt32(),
                            Location = video.GetProperty("pub_location").GetString(),
                            UpdateTime = DateTime.Now,
                        };                       
                        biliVideos.Add(biliVideo);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"[{DateTime.Now}]爬取[{index}]的数据时发生[{ex.Message}]错误");
                    }
                }
            }         
            catch (Exception ex)
            {
                logger.LogError($"[{DateTime.Now}]爬取[{index}]的数据时发生[{ex.Message}]错误");
            }
            return biliVideos;
        }
    }
}
